﻿namespace Windows32
{
    using System;
    using System.Runtime.InteropServices;
    using System.Text;

    public class Imm32
    {
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern int ImmCreateContext();
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern bool ImmDestroyContext(int hImc);
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern int ImmGetContext(int hwnd);
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr ImmGetContext(IntPtr hwnd);
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern bool ImmGetOpenStatus(int hImc);
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern bool ImmReleaseContext(int hwnd, int hImc);
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern bool ImmSetCandidateWindow(int hImc, ref CandidateForm frm);
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern bool ImmSetCompositionWindow(int hImc, ref CompositionForm frm);
        [DllImport("imm32.dll", CharSet = CharSet.Auto)]
        public static extern bool ImmSetStatusWindowPos(int hImc, ref POINT pos);
        [DllImport("Imm32.dll", CharSet = CharSet.Auto)]
        public static extern unsafe int ImmGetCompositionString(IntPtr hIMC, int dwIndex, sbyte* lpBuf, int dwBufLen);
        [DllImport("Imm32.dll")]
        public static extern IntPtr ImmAssociateContext(int hWnd, int hIMC);

        public static bool isImmOpen(int hWnd)
        {
            int hImc = ImmGetContext(hWnd);
            if (hImc == 0)
            {
                return false;
            }
            bool flag = ImmGetOpenStatus(hImc);
            ImmReleaseContext(hWnd, hImc);
            return flag;
        }

        public static void SetImmPos(int hWnd, int x, int y)
        {
            bool flag = false;
            uint lastError = 0;
            int hImc = ImmGetContext(hWnd);
            if (hImc != 0)
            {
                CompositionForm frm = new CompositionForm();
                frm.CurrentPos.x = x;
                frm.CurrentPos.y = y;
                frm.Style = 2;
                flag = ImmSetCompositionWindow(hImc, ref frm);
                lastError = Kernel32.GetLastError();
                ImmReleaseContext(hWnd, hImc);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CandidateForm
        {
            public int dwIndex;
            public int dwStyle;
            public POINT ptCurrentPos;
            public RECT rcArea;
        }

        public enum CandidateFormStyle
        {
            CFS_CANDIDATEPOS = 0x40,
            CFS_DEFAULT = 0,
            CFS_EXCLUDE = 0x80,
            CFS_FORCE_POSITION = 0x20,
            CFS_POINT = 2,
            CFS_RECT = 1
        }

        public const int GCS_COMPREADSTR = 0x0001;
        public const int GCS_COMPREADATTR = 0x0002;
        public const int GCS_COMPREADCLAUSE = 0x0004;
        public const int GCS_COMPSTR = 0x0008;
        public const int GCS_COMPATTR = 0x0010;
        public const int GCS_COMPCLAUSE = 0x0020;
        public const int GCS_CURSORPOS = 0x0080;
        public const int GCS_DELTASTART = 0x0100;
        public const int GCS_RESULTREADSTR = 0x0200;
        public const int GCS_RESULTREADCLAUSE = 0x0400;
        public const int GCS_RESULTSTR = 0x0800;
        public const int GCS_RESULTCLAUSE = 0x1000;
        public const int WM_IME_COMPOSITION = 0x010F;
        public const int WM_CHAR = 0x0102;
        public const int WM_IME_STARTCOMPOSITION = 0x010D;
        public const int WM_IME_ENDCOMPOSITION = 0x010E;
        public const int WM_IME_SETCONTEXT = 0x0281;
        public const int WM_IME_NOTIFY = 0x0282;
        public const int WM_IME_CONTROL = 0x0283;
        public const int WM_IME_COMPOSITIONFULL = 0x0284;
        public const int WM_IME_SELECT = 0x0285;
        public const int WM_IME_CHAR = 0x0286;
        public const int WM_DEADCHAR = 0x0103;
        public const int WM_KEYDOWN = 0x0100;
        public const int WM_KEYUP = 0x0101;
        public const int WM_PASTE = 0x0302;

        [StructLayout(LayoutKind.Sequential)]
        public struct CompositionForm
        {
            public int Style;
            public POINT CurrentPos;
            public RECT Area;
        }
    }
}

